#ifndef GUN_HH_
# define GUN_HH_

# include "Item.hh"

/** Gun is an abstract class
 */

// shd consider a global box for collisions ? or ignore them ?

// need a Gun chassis (4 scope, ...)

// allow throwing objects ?

// for all weapon type: same reload{Animation,Speed} ?
//  shd be : no
// common base ? (rotation on barrel axe [sens trigo]))


// a bullet is in a clip is in a gun
// Gun gun gun.weight == total weight (with clip [we don't care about bullets] / accessories)

// nb_hands = f(weight) ? => allow strength variations => 2 hands -> 1 hand
// cd use wounded = f(weight / recoil) ?

// allow customization (barrel, clip, ...)

/**
 ** Gun class sons:
 ** Rifle: 2 hands required Gun, allow light scope, flash suppressor...
 ** Shotgun 2 hands required Gun, spread, no scope
 ** Handgun 1 hand required Gun, no spread, clip
 ** SubMachineGuns 1 or 2 hands, not accurate
 ** MachineGuns 2 hands, *NOT* accurate powerfull, very heavy
 */
class Gun : public Item
{
public:
  Gun();
  virtual ~Gun();

  /** calculates recoil force and sets _recoil accordingly
   */
  virtual float calcRecoil(void) = 0; // NOTE: compil time calcul ? [templates]

  /** \return damages points
   ** calc based on :
   **     bullet velocity on impact,
   **     destination material resistance
   **     bullet density
   */
  virtual float impactDamages(float distance, float velocity, Bullet bullet, Material destination) = 0;


  // deadly formula && store result
  virtual float calcAccuracy();

  //
  virtual float getAccuracy();


  // annimation: gun rotation (each axes axe per axe, +/- 360 each)
  virtual void inspect();


private:
  // gun parts
  Clip _clip;
  Barrel _barrel;

  // caracteristics
  float _length; /// in metters // usefull ? (barrel length)

  float _recoil; /// recoil coefficient, use to calc _accuracy && new Gun position
  float _rate; /// in bullets per second  (=> calc time before each shot)
  /*
   * accuracy is :
   * a percentage ? chance to hit target, far from x meters ?
   * max impact distance from the target ?
   * both ?
   */
  float _accuracy;

  // Media Parts
  Sound _sound; /// shooting sound
  Animation _reloadingAnimation; // = f (stress_level ? / wounds)
  animation _dropWeapon; // uses player velocity
  Animation _switchingAnimation; // display when changing weapon [=f(inventory)]
  Animation _rearmingAnimation; /// animation played between each shot

  // opti
  Model3D _fps; /// the Model3D we display, using the gun

  // accessories: 'can we put a: '
  bool _clip; /// clip || one bullet at a time gun (shotgun / handgun)
  bool _handle;
  bool _biPod; /// any bi-pod ?
  bool _scope; /// any scope on it ?
  bool _flashlight; /// fixable flashlight
  bool _strap; /// prevent non voluntary drop [fr sangle]
  bool _handleStrap; /// is there a strap under the handle ?
  bool _bushbag; /// auto-collect bushes [Fr: douilles]

  /** needed time (in miliseconds) for a human to operate the Gun,
   ** without loosing accuracy (not counting on barrel heat)
   */
  float _readiness; /// use to calc total available time between each shot (more humanly than mechanic), based on _weight and _length // allow to override, accuracy killer
  bool _inspected; /// have it been inspected ? -> faster reload, discover alternate fire mode...
};

#endif /* !GUN_HH_ */
